home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr40
/
x1j4_src.zip
/
TNL7B2.C
< prev
next >
Wrap
Text File
|
1995-02-12
|
29KB
|
1,139 lines
/*****************************************************************************/
/* */
/* */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* *************** *************** */
/* ***************** ***************** */
/* *************** *************** */
/* ***** ***** TheNet */
/* ***** ***** Portable. Compatible. */
/* ***** ***** Public Domain */
/* ***** ***** NORD><LINK */
/* */
/* This software is public domain ONLY for non commercial use */
/* */
/* */
/*****************************************************************************/
/* Level 7B, Befehlsinterpreter, Befehle */
/* Version 1.01 */
/* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig */
/* 08-MAY-88 */
/* Modified by G8KBB - Jan 91 */
/* - Use of register keyword for code reduction */
/* - Use all.h header file */
/* - add command 'stats' conditionally on definition of STATSCMD */
/* - add host command optionally on HOSTCMD definition */
/* - add 'bbs' command optionally on HOSTCMD */
/* - add 'mheard' support */
/* - conditionally, include MODE command and reuse common code in PARAM */
/* - add TALK command optionally on TALKCMD */
/* - add LINKS command optionally on LINKSCMD */
/* - add calibrate command optionally on CWID */
/* - add DXcluster command optionally on DXCLUSTER if HOSTCMD defined */
/* - add hostalias, bbsalias, dxcalias & alias commands */
/* - add bye and quit commands */
/* - add manager and associated audit command */
/* - add closedown command */
/* - add help command */
/* - add btext and ctext commands & make them & info multi line */
/* - add calibrate command if cwid is loaded to permit calibration of tx*/
/* - add UI command to permit arbitrary UI frames to be sent */
/* - add acl command and associated subsystems to manage acls */
/* This half of the command interpreter commands contains the following :
* STATS HOST HOSTALIAS BBS BBSALIAS
* DXCLUSTER DXCALIAS BYE/QUIT MHEARD TALK
* LINKS MANAGER CLOSEDOWN HELP BTEXT
* CTEXT AUDIT CALIBRATE UI ACL
*/
/*
* September 1993 - released as TheNet X-1J
*/
/* Added S meter support and adc command
* update ccpmh for texnet display
*/
#include "all.h"
#include "tntyp.h" /* Definition der Typen */
#include "tnl7be.h" /* externe Definitionen */
char undefined[] = "undefined";
char local_host[] = "Local host";
char is[] = " is ";
#ifdef STATSCMD
/*---------------------------------------------------------------------------*/
VOID ccpsts() /* Befehl STATS */
{
register mhtyp *bufpoi; /* Buffer fuer Meldung */
register unsigned i;
bufpoi = putals("Statistics");
pstats("\015L1 Tx % : ", txstat, NUM1STATS, bufpoi );
pstats("\015L1 DCD% : ", rxstat, NUM1STATS, bufpoi );
pstats("\015L1 RxOvr: ", L2RXOVR, NUMPORTS*2, bufpoi );
pstats("\015L1 TxUnd: ", L2TXUND, NUMPORTS*2, bufpoi );
pstats("\015L2 RxCRC: ", L2RXCRC, NUMPORTS*2, bufpoi );
pstats("\015L2 heard: ", L2HDCNT, NUMPORTS*2, bufpoi );
pstats("\015L2 recvd: ", L2RXCNT, NUMPORTS*2, bufpoi );
pstats("\015L2 sent : ", L2TXCNT, NUMPORTS*2, bufpoi );
pstats("\015L2 RxRNR: ", L2RXRNR, NUMPORTS*2, bufpoi );
pstats("\015L2 RxREJ: ", L2RXREJ, NUMPORTS*2, bufpoi );
pstats("\015L2 TxRNR: ", L2TXRNR, NUMPORTS*2, bufpoi );
pstats("\015L2 TxREJ: ", L2TXREJ, NUMPORTS*2, bufpoi );
pstats("\015L2 fails: ", L2FAILS, NUMPORTS*2, bufpoi );
pstats("\015L3 g'wyd: ", l3gwcnt, 2, bufpoi );
pstats("\015L4 recvd: ", L4RXCNT, 2, bufpoi );
pstats("\015L4 sent : ", L4TXCNT, 2, bufpoi );
pstats("\015Buffers : ", minbuf, NUM1STATS, bufpoi );
pstats("\015CPU loop: ", cpucnt, NUM1STATS, bufpoi );
#ifdef MONITORCMD
putstr("\015Timers : ", bufpoi ); /* print the internal timers */
putnum_and_space( uptime, bufpoi ); /* as the time since warmstart */
putnum( runtime, bufpoi ); /* then the total runtime since cold*/
#endif
#ifdef PORTFLUSH
pstats("\015L1 flush: ", flushed, NUMPORTS, bufpoi );
#endif
seteom(bufpoi); /* Endekennung dran */
}
VOID pstats( string, values, count, bufpoi )
char *string;
register unsigned *values;
register unsigned count;
register mhtyp *bufpoi;
{
putstr( string, bufpoi );
while( count-- )
putnum_and_space( *values++, bufpoi );
}
VOID putnum_and_space( value, bufpoi )
unsigned value;
register mhtyp *bufpoi;
{
putnum( value, bufpoi ); /* print minimum buffer values */
putchr( ' ', bufpoi ); /* followed by a space */
}
#endif
#ifdef HOSTCMD
/*---------------------------------------------------------------------------*/
VOID ccphst()
{
ccp_helper( hostid, &hidlen, ccpc13, 1 );
}
VOID ccphoa()
{
ccp_alias_helper( hostalias, ccpc31 );
}
VOID ccpbbs()
{
ccp_helper( bbsid, &bbslen, ccpc15, 0 );
}
VOID ccpbba()
{
ccp_alias_helper( bbsalias, ccpc29 );
}
VOID ccpali()
{
ccp_alias_helper( alias, ccpc33 );
}
#ifdef DXCLUSTER
VOID ccpdxc()
{
ccp_helper( dxcid, &dxclen, ccpc23, 0 );
}
VOID ccpdxa()
{
ccp_alias_helper( dxcalias, ccpc30 );
}
#endif /* DXCLUSTER */
/*---------------------------------------------------------------------------*/
VOID ccp_helper( id, len, prompt, localflag )
register char *id;
register char *len;
char *prompt;
unsigned localflag;
{
register mhtyp *bufpoi; /* Buffer fuer Meldung */
if( clicnt /* > 0 */ )
{
if (issyso() && *clipoi != '?' ) /* must be sysop & not asking*/
set_call( id, len ); /* in order to set the call */
bufpoi = putals( prompt );
putstr( is, bufpoi ); /* Info mit Header */
putstr( *id ? id : (localflag ? local_host : undefined ), bufpoi);
seteom(bufpoi); /* Endekennung dran */
}
else
{
if( *len > 0 ) /* if a host callsign has been set */
{
clipoi = id; /* then fool connect into calling it */
clicnt = *len;
con_try_msg( id );
#ifdef MODIFIED
ccp_con();
#else
ccpcon();
#endif
}
else if( localflag )
{
clicnt = 0; /* otherwise connect to local host */
con_try_msg( local_host );
#ifdef MODIFIED
ccp_con();
#else
ccpcon();
#endif
}
else
{
bufpoi = putals( "No " );
putstr( prompt, bufpoi );
putstr( " set", bufpoi );
seteom( bufpoi );
}
}
}
/* helper utility to host and bbs commands that stores the callsign set
* by the sysop
* Accept up to 7 characters, and terminate if '*' is entered.
* '*' is used to clear the entry.
*/
VOID set_call( string, size )
register char *string;
char *size;
{
register unsigned chaptr;
chaptr = 0;
while (clicnt != 0 && chaptr < 9 && *clipoi != '*' )
{
string[chaptr++] = *clipoi;
nxtcli();
}
string[chaptr] = 0;
*size = chaptr;
}
VOID ccp_alias_helper( id, prompt )
register char *id;
char *prompt;
{
register mhtyp *bufpoi; /* Buffer fuer Meldung */
char tmpbuf[7];
if (issyso() && *clipoi != '?' ) /* must be sysop & not asking*/
{
if( *clipoi == '*' )
cpy6ch( id, nulide );
else if( getide( tmpbuf ) > 0 )
cpy6ch( id, tmpbuf );
}
bufpoi = putals( prompt );
putstr( is, bufpoi ); /* Info mit Header */
if( *id == ' ' )
putstr( undefined, bufpoi );
else
putcal( id, bufpoi );
seteom(bufpoi); /* Endekennung dran */
}
#endif /* HOSTCMD */
#ifdef MODIFIED
/*---------------------------------------------------------------------------*/
VOID ccpbye()
{
if( hlpflg & 4 )
putmsg("Goodbye.");
disusr( userpo->cblk_u, userpo->typ_u );
kilusr();
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef MONITORCMD
#ifdef L3MONITOR
VOID ccpmh()
{
mh_helper( &heardl, &mhlcount, YES );
}
VOID ccpmh3()
{
mh_helper( &l3heardl, &l3mhlcnt, NO );
}
VOID mh_helper( list, count, isl2list )
MHEARD *list;
unsigned char *count;
BOOLEAN isl2list;
{
register mhtyp *bufpoi; /* Buffer fuer Meldung */
register MHEARD *mhp;
register unsigned i;
unsigned mins;
signed dB;
if( clicnt && issyso() )
{
i = nextnumber(); /* neuen Wert holen */
if( i <= MAXHEARDLIST )
*count = i;
}
else if( *count )
{
bufpoi = putals("\015Callsign Pkts Port Time ");
if( isl2list )
{
#ifdef METERS
if( meterflags & DEVMETER_ENABLE )
putstr( "Dev. ", bufpoi );
if( meterflags & SMETER_ENABLE )
putstr( meterflags & SMETER_AS_S ? "Sig. " : "dBm ", bufpoi );
#endif
putstr( " Type", bufpoi);
}
mhp = (MHEARD *)list->prevhb;
while( mhp != (MHEARD *)list )
{
putchr('\015', bufpoi );
bufpoi->l4time = bufpoi->putcnt;
putid( mhp->call, bufpoi );
putspa( 12, bufpoi );
putnum( mhp->packets, bufpoi );
putspa( 19, bufpoi );
putnum( mhp->port, bufpoi );
putspa( 25, bufpoi );
i = seconds-mhp->lastheard;
mins = i / 60;
putnum( mins / 60, bufpoi );
putchr(':', bufpoi );
putnum( mins % 60, bufpoi );
putchr(':', bufpoi );
putnum( i % 60, bufpoi );
putspa( 35, bufpoi );
if( isl2list )
{
#ifdef METERS
if( meterflags & DEVMETER_ENABLE )
{
if( mhp->port == 0 )
{
i = ( mhp->dev * rxdev ) / 100;
if( mhp->dev > 254 )
putchr( '>', bufpoi );
putnum( i/10, bufpoi );
putchr( '.', bufpoi );
putnum( i % 10, bufpoi );
}
putspa( 42, bufpoi );
}
if( meterflags & SMETER_ENABLE )
{
if( mhp->port == 0 )
{
i = mhp->sig_level > rxsigmin ?
mhp->sig_level - rxsigmin : 0;
if( meterflags & SMETER_AS_S )
{
i = ( i * rxsmeter ) >> 8;
putchr( 'S', bufpoi );
putnum( i > 9 ? 9 : i , bufpoi );
if( i > 9 )
putchr( '+', bufpoi );
}
else
{
dB = (signed)( ( i * rxdb ) >> 8 ) - dbfloor;
if( dB < 0 )
putchr( '-', bufpoi );
putnum( dB < 0 ? 0-dB : dB, bufpoi );
}
}
putspa( meterflags & 1 ? 47 : 42, bufpoi );
}
#endif
if( mhp->isnode )
putstr( " Node", bufpoi );
if( mhp->istcpip )
putstr( " TCP/IP", bufpoi );
if( mhp->istexnet )
putstr( " TexNet", bufpoi );
}
else
putid( mhp->l3dest, bufpoi );
mhp = mhp->prevhb;
}
seteom( bufpoi );
}
else
putmsg( "MHEARD not running.");
}
#else /* L3MONITOR */
VOID ccpmh()
{
register mhtyp *bufpoi; /* Buffer fuer Meldung */
register MHEARD *mhp;
register unsigned i;
unsigned mins;
signed dB;
if( clicnt && issyso() )
{
i = nextnumber(); /* neuen Wert holen */
if( i <= MAXHEARDLIST )
mhlcount = i;
}
else if( mhlcount )
{
bufpoi = putals("\015Callsign Pkts Port Time ");
#ifdef METERS
if( meterflags & DEVMETER_ENABLE )
putstr( "Dev. ", bufpoi );
if( meterflags & SMETER_ENABLE )
putstr( meterflags & SMETER_AS_S ? "Sig. " : "dBm ", bufpoi );
#endif
putstr( " Type\015", bufpoi);
mhp = (MHEARD *)heardl.lprev;
while( mhp != (MHEARD *)&heardl )
{
bufpoi->l4time = bufpoi->putcnt;
putid( mhp->call, bufpoi );
putspa( 12, bufpoi );
putnum( mhp->packets, bufpoi );
putspa( 19, bufpoi );
putnum( mhp->port, bufpoi );
putspa( 25, bufpoi );
i = seconds-mhp->lastheard;
mins = i / 60;
putnum( mins / 60, bufpoi );
putchr(':', bufpoi );
putnum( mins % 60, bufpoi );
putchr(':', bufpoi );
putnum( i % 60, bufpoi );
putspa( 35, bufpoi );
#ifdef METERS
if( meterflags & DEVMETER_ENABLE )
{
if( mhp->port == 0 )
{
i = ( mhp->dev * rxdev ) / 100;
if( mhp->dev > 254 )
putchr( '>', bufpoi );
putnum( i/10, bufpoi );
putchr( '.', bufpoi );
putnum( i % 10, bufpoi );
}
putspa( 42, bufpoi );
}
if( meterflags & SMETER_ENABLE )
{
if( mhp->port == 0 )
{
i = mhp->sig_level > rxsigmin ?
mhp->sig_level - rxsigmin : 0;
if( meterflags & SMETER_AS_S )
{
i = ( i * rxsmeter ) >> 8;
putchr( 'S', bufpoi );
putnum( i > 9 ? 9 : i , bufpoi );
if( i > 9 )
putchr( '+', bufpoi );
}
else
{
dB = (signed)( ( i * rxdb ) >> 8 ) - dbfloor;
if( dB < 0 )
putchr( '-', bufpoi );
putnum( dB < 0 ? 0-dB : dB, bufpoi );
}
}
putspa( meterflags & 1 ? 47 : 42, bufpoi );
}
#endif
if( mhp->isnode )
putstr( " Node", bufpoi );
if( mhp->istcpip )
putstr( " TCP/IP", bufpoi );
if( mhp->istexnet )
putstr( " TexNet", bufpoi );
putchr('\015', bufpoi );
mhp = mhp->prevhb;
}
seteom( bufpoi );
}
else
putmsg( "MHEARD not running.");
}
#endif /* L3MONITOR */
#endif
/*---------------------------------------------------------------------------*/
#ifdef TALKCMD
/* TALK command. Firstly, send a message to all stations currently in the
* conference informing them that a new station has joined them. Then set
* the status to 4 so that the user is in the conference. Then, if the
* user had put text after the talk command, send that text to all users
* who are not in the conference but are connected idle to the switch.
* Finally, send a message to the user telling him he is in the conference.
*/
VOID ccpcht()
{
notify( myid, 4, this_station(), NULL, " has joined you.", 16 );
userpo->status = 4;
if( clicnt > 0 )
notify( this_station(), 1, NULL, NULL, clipoi, clicnt );
putmsg("Talk mode. Type '/ex' to leave.");
}
/* helper to the above - return a pointer to the callsign of this user
*/
char *this_station()
{
return( calofs( 'U', userpo->cblk_u, userpo->typ_u ) );
}
/* helper utility to TALK command. sends a message from 'sender' to all
* level 7 switch users whose current status matches that given. The
* message consists of an optional callsign followed by the message text
* Also, do not send the msg to the user who sent it ( ie userpo-> )
*
* The optionalcalls are either callsigns or numeric values
* depending on the setting of the top 2 bits of status.
*/
VOID notify( sender, status, optionalcall1, optionalcall2, msg, msglength )
char *sender;
int status, msglength;
char *optionalcall1, *optionalcall2;
char *msg;
{
register mhtyp *bufpoi;
register usrtyp *usrptr;
register int i;
char *ptr;
for( usrptr = (usrtyp *)usccpl.lnext; /* loop thru all ccp */
(usrtyp *)&usccpl != usrptr; /* users */
usrptr = usrptr->unext )
{
if( (usrptr->status == (status & 0x3f)) && (usrptr != userpo) && nmbfre >= 200)
{
bufpoi = (mhtyp *)allocb();
bufpoi->l2lnk = usrptr->cblk_u;
bufpoi->usrtyp = usrptr->typ_u;
putid( sender, bufpoi );
putstr( ">> ", bufpoi );
if( status & 0x80 )
putnum_and_space( optionalcall1, bufpoi );
else if( optionalcall1 != NULL )
putid_and_space( optionalcall1, bufpoi );
if( status & 0x40 )
putnum_and_space( optionalcall2, bufpoi );
else if( optionalcall2 != NULL )
putid_and_space( optionalcall2, bufpoi );
i = msglength;
ptr = msg;
while( i-- > 0 )
putchr( *ptr++, bufpoi );
seteom( bufpoi );
}
}
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef LINKSCMD
VOID ccplin()
{
register mhtyp *bufpoi;
register unsigned i;
register l2ltyp *link;
bufpoi = putals( "Links:" );
for( i = MAXL2L, link = lnktbl; i != 0 ; i--, link++ )
{
if( link->state != 0 ) /* L2SDSCES */
{
putchr( '\015', bufpoi );
putid_and_space( link->srcid, bufpoi );
putid_and_space( link->dstid, bufpoi );
putdil( link->viaid, bufpoi );
putchr( ' ', bufpoi );
putnum_and_space( link->state, bufpoi );
putnum_and_space( link->liport, bufpoi );
putnum_and_space( link->tries, bufpoi );
}
}
seteom( bufpoi );
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef MANAGED
char L7id[] = "L7 `";
/* The manager command does the same as sysop, but sets state to 5 so that
* the command interpreter will set it to 6 if successful.
*/
VOID ccpman()
{
ccpsys();
userpo->status = 5;
}
#ifdef CLOSEDOWN
/*---------------------------------------------------------------------------*/
/* The closedown command shuts down the node if executed properly.
* If not, you forfit sysop status
*/
VOID ccpclo()
{
if( issyso() && ( upcase( *clipoi ) == 'A' ) )
{
ccpsys();
userpo->status = 7;
userpo->sysflg = 0;
}
}
#endif
#ifdef MODIFIED
/*---------------------------------------------------------------------------*/
/* The help command prints out an interesting message
*/
VOID ccphlp()
{
putmsg( helpmsg );
}
/*---------------------------------------------------------------------------*/
/* The beacon text command sets an optional string on the beacon packet
*/
VOID ccpbtx()
{
settxt( beatxt, 79 );
putmsg( beatxt );
}
/*---------------------------------------------------------------------------*/
/* The connect-text command sets an optional string on connect
*/
VOID ccpctx()
{
settxt( contxt, 79 );
putmsg( contxt );
}
VOID settxt( string, length )
register char *string;
register unsigned length;
{
register unsigned chaptr;
if( issyso() )
{
chaptr = 0;
if( *clipoi != '*' )
{
while( string[chaptr] )
chaptr++;
while( clicnt != 0 && chaptr < length )
{
string[chaptr++] = *clipoi;
nxtcli();
}
if( chaptr < length )
string[chaptr++] = '\r';
}
string[chaptr] = '\0';
}
}
#endif
#endif
/*---------------------------------------------------------------------------*/
#ifdef CWID
/* Calibrate command. Only works for the sysop.
*/
VOID ccpcal()
{
if( !issyso() ) /* check if sysop */
return;
calper = nextnumber(); /* get desired period */
if( calper < 1 || calper > 60 ) /* only do it if 1 -> 60 sec*/
return;
caltog = nextnumber(); /* get optional toggle per. */
if( caltog < 1 || caltog > calper ) /* force to be 1 -> calper */
caltog = calper+1;
#ifndef MSDOS
if( cwstate == 3 ) /* only do it if not doing cwid at moment */
{
cwstate = -2; /* set state to -2 to indicate cal */
kicktx( HDLCPORT ); /* and go for it ! */
}
else
#endif
putmsg("Busy.");
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef MODIFIED
/* this function is used by ccpbbs etc to give a friendly message to the user
*/
VOID con_try_msg( callsign )
char *callsign;
{
register mhtyp *bufpoi;
if( hlpflg & 1 )
{
bufpoi = putals("Please wait, trying ");
putstr( callsign, bufpoi );
seteom( bufpoi );
}
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef MODIFIED
/* This command is used to send an arbitrary UI frame from the switch
* The syntax is :
* UI dest text_that_is_to_be_sent
*/
VOID ccpui()
{
char call[7];
register mhtyp *bufpoi;
if( !skipspace() || !getcal( &clicnt, &clipoi, 0, call))
return;
(bufpoi = (mhtyp *)allocb())->pid = PID_NO_L3;
while( clicnt /* > 0 */ )
{
putchr( *clipoi, bufpoi );
nxtcli();
}
putchr( '\015', bufpoi );
rwndmb( bufpoi );
sdui( beadil, call, this_station(), HDLCPORT, bufpoi );
dealmb( bufpoi );
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef ACL
/* ACL command interface routine.
* ACL with no parameters ( or if not sysop ) prints the ACL
* If a parameter is given, it must be of one of the following syntax types
* ACL callsign + value
* ACL callsign -
* ACL * value
*
* The first makes an entry, the second deletes one, the last sets the default
*/
VOID ccpacl()
{
register mhtyp *bufpoi;
register unsigned i;
register ACLMB *aclp;
char callsign[7];
if( !issyso() )
{
i = 0;
aclp = acl.prevaclb;
bufpoi = putals("ACL: Default ");
putnum( acl_default, bufpoi );
putstr( ", Mask ", bufpoi );
putnum( acl_mask, bufpoi );
while( aclp != &acl )
{
if( aclp->entry[i].call[0] != '\0' )
{
putchr( '\r', bufpoi );
bufpoi->l4time = bufpoi->putcnt;
putid( aclp->entry[i].call, bufpoi );
putspa( 10, bufpoi );
putnum( aclp->entry[i].value, bufpoi );
}
if( ++i >= 4 )
{
i = 0;
aclp = aclp->prevaclb;
}
}
seteom( bufpoi );
}
else if( *clipoi == '*' )
{
nxtcli();
acl_default = nextnumber();
}
else if( *clipoi == '&' )
{
nxtcli();
acl_mask = nextnumber();
}
else if( !getcal( &clicnt, &clipoi, 0, callsign ) )
invcal();
else if( *clipoi == '-' )
{
if( !acl_delete( callsign ) )
putmsg("Error in deleting entry");
}
else if( *clipoi == '+' )
{
nxtcli();
if( ! skipspace() )
putmsg("You must give a value!");
else if( !acl_add( callsign, nextnumber() ) )
putmsg("Error in adding value");
}
else
putmsg("Syntax error");
}
/* This function, called by ccpacl() adds or updates an entry in the list
*
* It returns TRUE if it succeeds
* FALSE if it fails ( ie not enough RAM )
*/
acl_add( call, value )
register char *call;
unsigned value;
{
/* check if there is already an entry for this call
*/
if( !acl_find( call, 1 ) )
{
/* If not, create or find space for a new entry
* and then copy the callsign in. acl_free() will
* return FALSE if there is not enough space.
*/
if( acl_free() )
cpyid( aclentry->call, call );
else
return( FALSE );
}
/* now copy the acl value into the entry
*/
aclentry->value = value;
return( TRUE );
}
/* This function, called by ccpacl() is used to delete an entry
*
* It returns TRUE on success
* FALSE on failure ( ie no match found for callsign )
*/
acl_delete( call )
char *call;
{
register int i;
/* give up if no entry found for callsign
*/
if( !acl_find( call, 1 ) )
return( FALSE );
/* delete the entry by setting first char of callsign to null
*/
aclentry->call[0] = '\0';
/* now count the number of deleted entries in this buffer
* If all 4 are now unused, free up the buffer
*/
for( i=0; i<4 && aclcur->entry[i].call[0] == '\0'; i++ )
;
if( i == 4 )
dealoc( unlink( aclcur ) );
return( TRUE );
}
/* This function finds the first free space to store an ACL entry,
* either as the first hole found or as the first entry in a new buffer
*/
acl_free()
{
register ACLMB *aclp;
register int i;
i = 0;
aclp = acl.prevaclb;
while( aclp != &acl )
{
/* if the entry is free, point to it and return TRUE
*/
if( aclp->entry[i].call[0] == '\0' )
{
aclentry = &aclp->entry[i];
aclcur = aclp;
return( TRUE );
}
/* otherwise, step on to next entry, or next buffer if
* all 4 have been checked
*/
if( ++i >= 4 )
{
i = 0;
aclp = aclp->prevaclb;
}
}
/* no entry is unused, so if there is lots of space,
* allocate a new buffer
*/
if( nmbfre < 200 )
{
aclentry = aclcur = NULL;
return( FALSE );
}
/* now point to it, and mark all its entries as unused
* then link it into the linked list
*/
aclcur = aclp = allocb();
for( i = 0; i < 4; i++ )
aclp->entry[i].call[0] = '\0';
relink( aclp, acl.nextaclb );
aclentry = &aclp->entry[0];
return( TRUE );
}
/* This routine looks for an entry that matches call[].
* If type is TRUE, it must also match SSID, otherwise SSID is ignored
*/
acl_find( call, type )
register char *call;
{
register ACLMB *aclp;
register int i;
i = 0;
aclp = acl.prevaclb;
while( aclp != &acl )
{
/* try to match either using or without SSID
* If match found, point to it & return
*/
if(( type && cmpid( call, aclp->entry[i].call ))
||
( !type && cmpcal( call, aclp->entry[i].call )))
{
aclentry = &aclp->entry[i];
aclcur = aclp;
return( TRUE );
}
/* step on thru 4 entries per buffer, then all buffers
*/
if( ++i >= 4 )
{
i = 0;
aclp = aclp->prevaclb;
}
}
/* failed to find match - clear pointers and return FALSE
*/
aclentry = aclcur = NULL;
return( FALSE );
}
/* THIS IS THE MAIN ACL INTERFACE ROUTINE FOR THE SWITCH FUNCTIONS
* Given a callsign, it returns an ACL value for that callsign,
* as either the value stored against that callsign with SSID match
* or as the first matching entry ignoring SSID where that entry has
* the IGNORE_SSID bit set
*/
acl_entry( callsign )
register char *callsign;
{
if( acl_find( callsign, 1 ) )
return( aclentry->value );
else if( acl_find( callsign, 0 ) && ( aclentry->value & ACL_IGNORE_SSID ))
return( aclentry->value );
return( acl_default );
}
#endif
/*---------------------------------------------------------------------------*/
#ifdef METERS
VOID ccpadc()
{
register mhtyp *bufpoi;
bufpoi = putals("\r");
if( meterflags & CH3_ENABLE )
adc_show( CH3_START, adcmult1, adcofs1, CH3_DIV1000,
CH3_DECIMALS, units1, bufpoi );
if( meterflags & CH4_ENABLE )
adc_show( CH4_START, adcmult2, adcofs2, CH4_DIV1000,
CH4_DECIMALS, units2, bufpoi );
#ifdef ALL_METERS
if( meterflags & CH1_ENABLE )
adc_show( CH1_START, adcmult3, adcofs3, CH1_DIV1000,
CH1_DECIMALS, units3, bufpoi );
if( meterflags & CH2_ENABLE )
adc_show( CH2_START, adcmult4, adcofs4, CH2_DIV1000,
CH2_DECIMALS, units4, bufpoi );
#endif
seteom( bufpoi );
}
adc_show( channel, multiplier, offset, div_1000, decimals, units, bufpoi )
register mhtyp *bufpoi;
signed multiplier, offset;
unsigned channel, div_1000, decimals;
char *units;
{
register signed i;
i = ( (signed) adc_read( channel ) - offset ) * multiplier;
if( i < 0 )
{
putchr( '-', bufpoi );
i = - i;
}
i /= ( meterflags & div_1000 ) ? 100 : 10;
putnum( i / 10, bufpoi );
if( meterflags & decimals )
{
putchr( '.', bufpoi );
putnum( i % 10, bufpoi );
}
putchr( ' ', bufpoi );
putstr( units , bufpoi );
}
#ifdef PORTABLE
adc_read( channel )
{
return( random() & 0xff );
}
#else
#asm
.z80
public adc_read_
ADC equ 32
extrn DIinc_, decEI_
adc_read_: pop hl
pop de
push de
push hl
call DIinc_
ld a,e
out (ADC),A
ld a,31
adcr1: dec a
jr nz, adcr1
in a,(ADC)
call decEI_
ld l,a
ld h,0
or a
ret
.8080
#endasm
#endif
/*---------------------------------------------------------------------------*/
/* The adc channel 1 text command sets an optional string for adc units
*/
VOID ccpad1()
{
ccp_adcx( units1 );
}
/*---------------------------------------------------------------------------*/
/* The adc channel 2 text command sets an optional string for adc units
*/
VOID ccpad2()
{
ccp_adcx( units2 );
}
#ifdef ALL_METERS
/*---------------------------------------------------------------------------*/
/* The adc channel 3 text command sets an optional string for adc units
*/
VOID ccpad3()
{
ccp_adcx( units3 );
}
/*---------------------------------------------------------------------------*/
/* The adc channel 4 text command sets an optional string for adc units
*/
VOID ccpad4()
{
ccp_adcx( units4 );
}
#endif /* ALL_METERS */
VOID ccp_adcx( string )
register char *string;
{
settxt( string, 12 );
putmsg( string );
}
#endif
/*--- Ende Level7B ----------------------------------------------------------*/